import pkg_resources

class bag(dict):
    """Similar to a dictionary, but values in the dictionary are accessible
    directly on the object as properties. Useful for creating mock objects
    in tests or to return from a JSON request.
    
    Example:

        >>> from pdx.core import bag
        >>> b = bag(a=1, b=2)
        >>> print isinstance(b, dict)
        True
        >>> print set(b.keys())
        set(['a', 'b'])
        >>> print b['a']
        1
        >>> print b['b']
        2
        >>> print b.a
        1
        >>> print b.b
        2
        >>> b.c = 3
        >>> print b['c']
        3
        >>> b.d = 4
        >>> print b['d']
        4
        >>> print b.d
        4
    """
    
    def __init__(self, *l, **kw):
        dict.__init__(self, *l, **kw)
        self.__dict__.update(self)
    def __setitem__(self, k, v):
        dict.__setitem__(self, k,v)
        self.__dict__[k] = v
    def __setattr__(self, k, v):
        dict.__setitem__(self, k,v)
        self.__dict__[k] = v
    @classmethod
    def from_object(klass, obj, fields):
        b=klass()
        for f in fields:
            b[f] = getattr(obj, f)
        return b
    def update_if_not(self, new_dict, excluded_value):
        for k,v in new_dict.items():
            if v == excluded_value: continue
            self[k] = v
        return self

def walk_pkg(pkg_or_req, name, dirpath=None):
    '''Yield dirpath, dirnames, filenames like os.walk'''
    if dirpath is None:
        rname = name
    else:
        rname = '/'.join((dirpath, name))
    dirnames = []
    filenames = []
    if pkg_resources.resource_exists(pkg_or_req, rname):
        for entry in pkg_resources.resource_listdir(pkg_or_req, rname):
            if pkg_resources.resource_isdir(pkg_or_req, '/'.join((rname, entry))):
                dirnames.append(entry)
            else:
                filenames.append(entry)
        yield rname, dirnames, filenames
        for d in dirnames:
            if dirpath is None:
                new_path = name
            else:
                new_path = '/'.join((dirpath, name))
            for t in walk_pkg(pkg_or_req, d, new_path): yield t
    else:
        pass

